/**
 * Copyright [2019] [LiBo/Alex of copyright liboware@gmail.com ]
 * <p>
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * <p>
 * http://www.apache.org/licenses/LICENSE-2.0
 * <p>
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.hyts.rxjava.chain;

import rx.Observable;
import rx.Scheduler;
import rx.functions.Action1;
import rx.schedulers.Schedulers;

import java.util.Optional;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;

/**
 * @project-name:coffice-toolbox
 * @package-name:com.hyts.rxjava.task
 * @author:LiBo/Alex
 * @create-date:2019-08-30 13:54
 * @copyright:libo-alex4java
 * @email:liboware@gmail.com
 * @description:
 */
public class Task {


    private static final long DEFAULT_REPEATE_SECONDS = 1;

    private static final TimeUnit DEFAULT_TIME_UNIT = TimeUnit.SECONDS;


    /*********************************************repeate execute chain 执行环对象**（无入参）*******************************************************/

    /**
     * 重复执行相关操作服务
     * @param repeate
     * @param timeUnit
     */
    public static void repeateExecute(Long repeate, TimeUnit timeUnit, Scheduler scheduler, Action1 function){
        timeUnit = Optional.ofNullable(timeUnit).orElse(DEFAULT_TIME_UNIT);
        repeate = Optional.ofNullable(repeate).orElse(DEFAULT_REPEATE_SECONDS);
        scheduler = Optional.ofNullable(scheduler).orElse(Schedulers.io());
        Observable.merge(Observable.interval(repeate,timeUnit).subscribeOn(scheduler),
                Observable.empty()).toBlocking().forEach(function);
    }

    /**
     * 重复执行相关操作服务
     * @param repeate
     * @param timeUnit
     * @param function
     */
    public static void repeateExecute(Long repeate, TimeUnit timeUnit, Action1 function){
         repeateExecute(repeate,timeUnit,null,function);
    }

    /**
     * 重复执行相关操作服务
     * @param repeate
     * @param function
     */
    public static void repeateExecute(Long repeate,Action1 function){
        repeateExecute(repeate,null,function);
    }

    /**
     * 重复执行相关操作服务
     * @param function
     */
    public static void repeateExecute(Action1 function){
        repeateExecute(null,function);
    }

    /*********************************************repeate execute chain 执行环对象**（有入参）*******************************************************/

    /**
     * repeate执行操作
     * @param repeate
     * @param timeUnit
     * @param scheduler
     * @param observable
     * @param dealResult
     */
    public static void repeateExecute(Long repeate, TimeUnit timeUnit,
                                      Scheduler scheduler, Observable observable,
                                      Action1 dealData, Function dealResult){
        timeUnit = Optional.ofNullable(timeUnit).orElse(DEFAULT_TIME_UNIT);
        repeate = Optional.ofNullable(repeate).orElse(DEFAULT_REPEATE_SECONDS);
        scheduler = Optional.ofNullable(scheduler).orElse(Schedulers.io());
        Observable time = Observable.interval(repeate.longValue(),timeUnit).subscribeOn(scheduler);
        Observable.zip(observable,time,(param,t)->
            dealResult.apply(param)
        ).toBlocking().forEach(dealData);
    }

    /**
     * repeate执行操作
     * @param repeate
     * @param timeUnit
     * @param observable
     * @param action1
     * @param dealResult
     */
    public static void repeateExecute(Long repeate, TimeUnit timeUnit,Observable observable,Action1 action1,Function dealResult){
        repeateExecute(repeate,timeUnit,null,observable,action1,dealResult);
    }

    /**
     * repeate执行操作
     * @param repeate
     * @param data
     * @param action1
     * @param dealResult
     */
    public static void repeateExecute(Long repeate, Observable data,Action1 action1,Function dealResult){
        repeateExecute(repeate,null,data,action1,dealResult);
    }

    /**
     * repeate执行操作
     * @param data
     * @param action1
     * @param dealResult
     */
    public static void repeateExecute(Observable data,Action1 action1,Function dealResult){
        repeateExecute(null,data,action1,dealResult);
    }


    public static void main(String[] args){
       /* Task.repeateExecute((param)->{
            System.out.println(param+"1231231");
        });*/
        Observable<String> data = Observable.just("1231","12312");
        Task.repeateExecute(data,(a)-> {a = ((String)a)+1;}
        ,(s)->{
            System.out.println(s);
            return s;
        });

    }

}
